import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.io.File;
import java.util.Date;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

public class MedicalRecordExplorer extends JInternalFrame implements ListSelectionListener, ChangeListener {

	private Patient patient;
	
	private JButton saveButton, cancelButton;
		
	//info panel
	private JTextField lastName, firstName, middleName;
	private JTextField height, weight;
	private JTextField bloodType;
	private JRadioButton male, female;
	private JTextField address, city, prov, postalCode, country, phone; 
	private JTextField emergencyLastName, emergencyFirstName, emergencyPhone;
	private String[] columnNames3 = {"Condition", "Description"};
	private JTable conditionsTable;
	
	
	//table for the medical history
	public JTable historyTable;
	private String[] columnNames = {"Date", "Physician"};
	private JScrollPane historyTableScroll;
	private JTextField historySearchField;
	private JTextField dateField, doctorField;
	private JTextPane descriptionField;
	
	//table for imaging
	public JTable imagingTable;
	private String[] columnNames2 = {"Date", "Image"};
	private JScrollPane imageTableScroll;
	private JTextField imageSearchField;
	private JTextField imageDateField;
	private JComboBox imageTypeField;
	private JTextPane imageNotesField;
	private JSlider imageChanger;
	private JLabel picLabel;
	
	//meds panel
	private JTable medsTable;
	private String[] columnNames4 = {"Medication", "Prescribed By", "Notes", "Active" };
	
	public MedicalRecordExplorer() {
		this(null);
	}
	
	public MedicalRecordExplorer(Patient p) {
		 if ( p == null ) {
			 super.setTitle("New Patient");
		 }
		 else {
			 patient = p;
			 super.setTitle( p.getLastName() + ", " + p.getFirstName() );
		 }
		 setBounds(75, 75, 650, 650);
	     setVisible(true);
	     getContentPane().setLayout( new BoxLayout( getContentPane(), BoxLayout.Y_AXIS ) );
	     setResizable(true);
	     setFrameIcon(null);
	     setClosable(true);
	     toFront();
	     
	     JPanel topPanel = new JPanel();
	     topPanel.setBackground( Color.white );
	     
	     JLabel welcome = new JLabel(p.getLastName() + ", " + p.getFirstName()  + "  (CHRID-" + p.getId() + ")" );
	     topPanel.add( welcome );
	     getContentPane().add( topPanel );
	     
	     JTabbedPane tabbedPane = new JTabbedPane( JTabbedPane.TOP );
	     getContentPane().add( tabbedPane );
	     
	     JPanel infoPanel = makePatientInfoPanel();
	     tabbedPane.add( "Patient Info", infoPanel );
	     
	     JPanel medicalHistoryPanel = makeMedicalHistoryPanel();
	     tabbedPane.add( "Medical History", medicalHistoryPanel );
	     
	     JPanel medicalImagingPanel = makeMedicalImagingPanel();
	     tabbedPane.add( "Medical Imaging", medicalImagingPanel );
	     
	     JPanel medicationsPanel = makeMedicationsPanel();
	     tabbedPane.add( "Medications", medicationsPanel );
	     
	     JPanel buttonsPanel = new JPanel();
	     buttonsPanel.setLayout( new BoxLayout(buttonsPanel, BoxLayout.X_AXIS ) );

	     
	     
	     saveButton = new JButton("Save");
	     buttonsPanel.add( saveButton );
	     cancelButton = new JButton("Cancel");
	     buttonsPanel.add( cancelButton );
	     getContentPane().add( buttonsPanel );
	     
	     
	     fillPatientInfo();
	     fillTableWithAllHistory();
	     fillTableWithAllImages();
	}
	
	private JPanel makeMedicationsPanel() {
		
		JPanel medicationsPanel = new JPanel();
		medicationsPanel.setBorder( BorderFactory.createEmptyBorder(10, 10, 10, 10));
		medicationsPanel.setLayout( new BoxLayout( medicationsPanel, BoxLayout.Y_AXIS ) );

		medsTable = new JTable();
		DefaultTableModel tableModel = new DefaultTableModel(columnNames4,0);
		medsTable = new JTable(tableModel);
		medsTable.setPreferredScrollableViewportSize(new Dimension(400, 900));
		JScrollPane medsTableScroller = new JScrollPane(medsTable);
		medsTable.setSelectionForeground( Color.white );
		medsTable.setSelectionBackground( new Color(184, 207, 229, 255) );
		medsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		medsTable.getColumnModel().getColumn(0).setPreferredWidth(150);
		medsTable.getColumnModel().getColumn(1).setPreferredWidth(115);
		medsTable.getColumnModel().getColumn(2).setPreferredWidth(255);
		medsTable.getColumnModel().getColumn(3).setPreferredWidth(60);
		
		medicationsPanel.add( medsTableScroller );
		
		JButton addButton = new JButton("+");
		addButton.setBackground(Color.GREEN);
		addButton.setMaximumSize(new Dimension(60,80));
		medicationsPanel.add( Box.createRigidArea(new Dimension(0,10)));
		medicationsPanel.add( addButton );
		addButton.setAlignmentX(CENTER_ALIGNMENT);
		
		Vector<Medication> m = patient.getMedications();
		for( int i = 0; i < m.size(); i++ ) {
			String[] r = { m.get(i).getName(), m.get(i).getPrescribedBy(), m.get(i).getNotes(), m.get(i).isActive() ? "Yes" : "No" };
			DefaultTableModel mo = (DefaultTableModel)(medsTable.getModel());
			mo.addRow( r );
		}
		
		return medicationsPanel;
	}
	
	private JPanel makePatientInfoPanel() {
		JPanel patientPanel = new JPanel();
		patientPanel.setLayout( new BoxLayout(patientPanel,BoxLayout.Y_AXIS));
		patientPanel.setBorder( BorderFactory.createEmptyBorder(10, 10, 10, 10));

		JPanel profilePanel = new JPanel( new GridLayout(4,4) );
		profilePanel.setBorder( BorderFactory.createTitledBorder(BorderFactory.createLineBorder(new Color(184, 207, 229, 255), 1), "Profile"));

		JLabel CHRIDlabel = new JLabel("CHRID");
		JLabel id = new JLabel(patient.getId() + "");
		profilePanel.add( CHRIDlabel );
		profilePanel.add(id);

		JLabel lastNameLabel = new JLabel("Last Name");
		lastName = new JTextField(20);
		profilePanel.add(lastNameLabel);
		profilePanel.add(lastName);

		JLabel firstNameLabel = new JLabel("First Name");
		firstName = new JTextField(20);
		profilePanel.add(firstNameLabel);
		profilePanel.add(firstName);

		JLabel middleNameLabel = new JLabel("Middle Name");
		middleName = new JTextField(20);
		profilePanel.add(middleNameLabel);
		profilePanel.add(middleName);

		JPanel sexPanel = new JPanel( new GridLayout(1,2));
		JLabel sexLabel = new JLabel("Sex");
		male = new JRadioButton("Male");
		female = new JRadioButton("Female");
		ButtonGroup g = new ButtonGroup();
		g.add(male);
		g.add(female);
		profilePanel.add( sexLabel );
		sexPanel.add( male );
		sexPanel.add( female );
		profilePanel.add( sexPanel );

		JLabel heightLabel = new JLabel("Height (cm)");
		height = new JTextField(20);
		profilePanel.add( heightLabel );
		profilePanel.add( height );

		JLabel weightLabel = new JLabel("Weight (kg)");
		weight = new JTextField(20);
		profilePanel.add( weightLabel );
		profilePanel.add( weight );

		JLabel bloodLabel = new JLabel("Blood Type");
		bloodType = new JTextField(20);
		profilePanel.add( bloodLabel );
		profilePanel.add( bloodType );

		patientPanel.add( profilePanel );

		JPanel contactPanel = new JPanel( new GridLayout(3,4) );
		contactPanel.setBorder( BorderFactory.createTitledBorder(BorderFactory.createLineBorder(new Color(184, 207, 229, 255), 1), "Contact Info"));

		JLabel addressLabel = new JLabel("Address");
		address = new JTextField(20);
		contactPanel.add(addressLabel);
		contactPanel.add(address);

		JLabel cityLabel = new JLabel("City");
		city = new JTextField(20);
		contactPanel.add(cityLabel);
		contactPanel.add(city);

		JLabel provLabel = new JLabel("Province");
		prov = new JTextField(20);
		contactPanel.add(provLabel);
		contactPanel.add(prov);

		JLabel countryLabel = new JLabel("Country");
		country = new JTextField(20);
		contactPanel.add(countryLabel);
		contactPanel.add(country);

		JLabel postalcodeLabel = new JLabel("Postal Code");
		postalCode = new JTextField(20);
		contactPanel.add(postalcodeLabel);
		contactPanel.add(postalCode);

		JLabel phoneLabel = new JLabel("Phone");
		phone = new JTextField(20);
		contactPanel.add(phoneLabel);
		contactPanel.add(phone);

		patientPanel.add( contactPanel );

		JPanel emergencyPanel = new JPanel( new GridLayout(2,4) );
		emergencyPanel.setBorder( BorderFactory.createTitledBorder(BorderFactory.createLineBorder(new Color(184, 207, 229, 255), 1), "Emergency Contact"));

		JLabel eLNL = new JLabel("Last Name");
		emergencyLastName = new JTextField(20);
		emergencyPanel.add(eLNL);
		emergencyPanel.add(emergencyLastName);

		JLabel eFNL = new JLabel("First Name");
		emergencyFirstName = new JTextField(20);
		emergencyPanel.add(eFNL);
		emergencyPanel.add(emergencyFirstName);

		JLabel ePL = new JLabel("Phone");
		emergencyPhone = new JTextField(20);
		emergencyPanel.add(ePL);
		emergencyPanel.add(emergencyPhone);

		emergencyPanel.add( new JLabel() );
		emergencyPanel.add( new JLabel() );

		patientPanel.add( emergencyPanel );

		JPanel conditionsPanel = new JPanel();
		conditionsPanel.setLayout( new BoxLayout( conditionsPanel, BoxLayout.X_AXIS));
		conditionsPanel.setBorder( BorderFactory.createTitledBorder(BorderFactory.createLineBorder(new Color(184, 207, 229, 255), 1), "Medical Conditions"));

		conditionsTable = new JTable();
		DefaultTableModel tableModel = new DefaultTableModel(columnNames3,0);
		conditionsTable = new JTable(tableModel);
		conditionsTable.setPreferredScrollableViewportSize(new Dimension(400, 50));
		JScrollPane conditionsTableScroller = new JScrollPane(conditionsTable);
		conditionsTable.setSelectionForeground( Color.white );
		conditionsTable.setSelectionBackground( new Color(184, 207, 229, 255) );
		conditionsPanel.add( conditionsTableScroller );
		conditionsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		conditionsTable.getColumnModel().getColumn(0).setPreferredWidth(150);
		conditionsTable.getColumnModel().getColumn(1).setPreferredWidth(this.getWidth()-288);

		JButton addButton = new JButton("+");
		addButton.setBackground(Color.GREEN);
		addButton.setPreferredSize(new Dimension(60,80));
		conditionsPanel.add( addButton );

		Vector<MedicalCondition> v = patient.getMedicalConditions();
		for( int i = 0; i < v.size(); i++ ) {
			String[] r = { v.get(i).getName(), v.get(i).getDescription() };
			DefaultTableModel m = (DefaultTableModel)(conditionsTable.getModel());
			m.addRow( r );
		}

		patientPanel.add( conditionsPanel );
		
		return patientPanel;
	}
	
	private void fillPatientInfo() {
		lastName.setText(patient.getLastName());
		middleName.setText(patient.getMiddleName());
		firstName.setText(patient.getFirstName());
		if(patient.getSex() == 'M' ) {
			male.setSelected(true);
			female.setSelected(false);
		}
		else {
			female.setSelected(true);
			male.setSelected(false);
		}
		height.setText(String.valueOf(patient.getHeight()));
		weight.setText(String.valueOf(patient.getWeight()));
		bloodType.setText(patient.getBloodType());
		address.setText(patient.getAddress());
		city.setText(patient.getCity());
		prov.setText(patient.getProvState());
		country.setText(patient.getCountry());
		postalCode.setText(patient.getPostalCode());
		phone.setText(patient.getPhone());
		emergencyFirstName.setText(patient.getEmergencyFirstName());
		emergencyLastName.setText(patient.getEmergencyLastName());
		emergencyPhone.setText(patient.getEmergencyPhone());
		
	}
	
	private JPanel makeMedicalHistoryPanel() {
		JPanel medicalHistoryPanel = new JPanel();
	     medicalHistoryPanel.setLayout( new BoxLayout(medicalHistoryPanel, BoxLayout.Y_AXIS) );
	     medicalHistoryPanel.setBorder( BorderFactory.createEmptyBorder(10, 10, 10, 10));
	     
	     historyTable = new JTable();
	     DefaultTableModel tableModel = new DefaultTableModel(columnNames,0);
	     historyTable = new JTable(tableModel);
	     historyTable.setPreferredScrollableViewportSize(new Dimension(400, 200));
	     historyTableScroll = new JScrollPane(historyTable);
	     historyTable.setSelectionForeground( Color.white );
	     historyTable.setSelectionBackground( new Color(184, 207, 229, 255) );
	     historyTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	     historyTable.getSelectionModel().addListSelectionListener(this);
	     
	     medicalHistoryPanel.add( historyTableScroll );
	     medicalHistoryPanel.add( Box.createRigidArea( new Dimension(0,10)));
	     
	     JPanel dynamicDataPanel = new JPanel();
	     dynamicDataPanel.setLayout( new BoxLayout(dynamicDataPanel, BoxLayout.Y_AXIS) );
	     
	     JPanel shortdynamicdatapanel = new JPanel();
	     shortdynamicdatapanel.setLayout( new BoxLayout(shortdynamicdatapanel, BoxLayout.X_AXIS) );
	     
	     JLabel dateLabel = new JLabel("Date");
	     shortdynamicdatapanel.add( dateLabel );
	     
	     dateField = new JTextField(20);
	     dateField.setEditable(false);
	     shortdynamicdatapanel.add( dateField );
	     
	     shortdynamicdatapanel.add( Box.createRigidArea( new Dimension(20,0)));
	     
	     JLabel doctorLabel = new JLabel("Doctor");
	     shortdynamicdatapanel.add( doctorLabel );
	     
	     doctorField = new JTextField(20);
	     doctorField.setEditable(false);
	     shortdynamicdatapanel.add( doctorField );
	     
	     dynamicDataPanel.add( shortdynamicdatapanel );
	     
	     dynamicDataPanel.add( Box.createRigidArea( new Dimension(0,10)));
	     
	     JPanel longdynamicdatapanel = new JPanel();
	     longdynamicdatapanel.setLayout( new BoxLayout(longdynamicdatapanel, BoxLayout.X_AXIS) );
	     
	     JLabel descriptionLabel = new JLabel("Description");
	     longdynamicdatapanel.add( descriptionLabel );
	     descriptionLabel.setAlignmentX(LEFT_ALIGNMENT);
	     
	     longdynamicdatapanel.add( Box.createRigidArea( new Dimension(this.getWidth()*2, 0)));
	     dynamicDataPanel.add( longdynamicdatapanel );
	     
	     dynamicDataPanel.add( Box.createRigidArea( new Dimension(0,5)));
	     
	     descriptionField = new JTextPane();
	     descriptionField.setEditable(false);
	     descriptionField.setPreferredSize(new Dimension(600,300));
	     dynamicDataPanel.add( descriptionField );
	     
	     medicalHistoryPanel.add( dynamicDataPanel );
	     
	     return medicalHistoryPanel;
	}
	
	private JPanel makeMedicalImagingPanel() {
		JPanel imagingPanel = new JPanel();
		imagingPanel.setLayout( new BoxLayout(imagingPanel, BoxLayout.Y_AXIS) );
		imagingPanel.setBorder( BorderFactory.createEmptyBorder(10, 10, 10, 10) );
		
		JPanel topPanel = new JPanel();
		topPanel.setLayout( new BoxLayout(topPanel, BoxLayout.X_AXIS) );
				
		 imagingTable = new JTable();
	     DefaultTableModel tableModel = new DefaultTableModel(columnNames2,0);
	     imagingTable = new JTable(tableModel);
	     imagingTable.setPreferredScrollableViewportSize(new Dimension(400, 300));
	     imageTableScroll = new JScrollPane(imagingTable);
	     imageTableScroll.setPreferredSize( new Dimension(400,300));
	     imagingTable.setSelectionForeground( Color.white );
	     imagingTable.setSelectionBackground( new Color(184, 207, 229, 255) );
	     imagingTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	     imagingTable.getSelectionModel().addListSelectionListener(this);
	     
	     topPanel.add( imageTableScroll );
	     
	     topPanel.add( Box.createRigidArea(new Dimension(10,1)));
	     
	     JPanel viewerPanel = new JPanel();
			viewerPanel.setLayout( new BoxLayout(viewerPanel,BoxLayout.Y_AXIS));
			
			Icon pic = new ImageIcon( "filler.jpg" );
			picLabel = new JLabel(pic);
			picLabel.setPreferredSize( new Dimension(256,256) );
			picLabel.setBorder( BorderFactory.createLineBorder(Color.black, 1));
			viewerPanel.add(picLabel);
			
			imageChanger = new JSlider();
			imageChanger.setPreferredSize( new Dimension(256,1));
			imageChanger.setEnabled( false );
			imageChanger.addChangeListener(this);
			viewerPanel.add( imageChanger );
			
			topPanel.add( viewerPanel );
	     
	     imagingPanel.add( topPanel );
	     imagingPanel.add( Box.createRigidArea(new Dimension(1,10)));
	     
	     JPanel bottomPanel = new JPanel();
	     bottomPanel.setLayout( new BoxLayout(bottomPanel,BoxLayout.Y_AXIS));
	     
	     JPanel shortdynamicdatapanel = new JPanel();
	     shortdynamicdatapanel.setLayout( new BoxLayout(shortdynamicdatapanel, BoxLayout.X_AXIS) );
	     
	     JLabel dateLabel = new JLabel("Date");
	     shortdynamicdatapanel.add( dateLabel );
	     
	     imageDateField = new JTextField(20);
	     imageDateField.setEditable(false);
	     shortdynamicdatapanel.add( imageDateField );
	     
	     shortdynamicdatapanel.add( Box.createRigidArea( new Dimension(20,0)));
	     
	     JLabel imageLabel = new JLabel("Image");
	     shortdynamicdatapanel.add( imageLabel );
	     
	     String[] imageTypes = { "Electron Microscopy", "X-Ray", "MRI", "Fluoroscopy", "PET", "Thermography", "Tomography", "Ultrasound" };
	     imageTypeField = new JComboBox( imageTypes );
	     shortdynamicdatapanel.add( imageTypeField );
	     
	     bottomPanel.add( shortdynamicdatapanel );
	     
	     bottomPanel.add( Box.createRigidArea( new Dimension(0,10)));
	     
	     JPanel longdynamicdatapanel = new JPanel();
	     longdynamicdatapanel.setLayout( new BoxLayout(longdynamicdatapanel, BoxLayout.X_AXIS) );
	     
	     JLabel descriptionLabel = new JLabel("Notes");
	     longdynamicdatapanel.add( descriptionLabel );
	     descriptionLabel.setAlignmentX(LEFT_ALIGNMENT);
	     
	     longdynamicdatapanel.add( Box.createRigidArea( new Dimension(this.getWidth()*2, 0)));
	     bottomPanel.add( longdynamicdatapanel );
	     
	     bottomPanel.add( Box.createRigidArea( new Dimension(0,5)));
	     
	     imageNotesField = new JTextPane();
	     imageNotesField.setEditable(false);
	     imageNotesField.setPreferredSize(new Dimension(600,200));
	     bottomPanel.add( imageNotesField );
	     
	     imagingPanel.add( bottomPanel );
	     
		
		return imagingPanel;
	}
	
	
	public void valueChanged(ListSelectionEvent evt ) {
		if ( evt.getSource().equals(historyTable.getSelectionModel()) ) {
			try {
				MedicalVisit v = getMedicalVisitFromTable( historyTable.getSelectedRow() );
				dateField.setText(v.getDate().toString());
				doctorField.setText(v.getDoctor());
				descriptionField.setText(v.getDescription());
			}
			catch(Exception x) {
				x.printStackTrace();
			}
		}
		else if ( evt.getSource().equals(imagingTable.getSelectionModel()) ) {
			if ( imagingTable.getSelectedRow() < 0 ) {
				imageChanger.setEnabled(false);
			}
			else {
				imageChanger.setEnabled(true);
				imageChanger.setMinimum(0);
				File dir = new File( getMedicalImageFromTable( imagingTable.getSelectedRow() ).getPath() );
				String[] files = dir.list();
				imageChanger.setMaximum(files.length);
				imageChanger.setValue(0);
				MedicalImage m = getMedicalImageFromTable( imagingTable.getSelectedRow() );
				imageDateField.setText(m.getDate().toString());
				imageTypeField.setSelectedItem( m.getType() );
				imageNotesField.setText(m.getDescription() );
				
				loadMRISlide(1);
			}
		}
	}
	
	private void fillTableWithAllHistory() {
		Vector<MedicalVisit> v = patient.getMedicalHistory();
		historyTable.setModel( new DefaultTableModel(columnNames, 0) );
		for( int i = 0; i < v.size(); i++ ) {
	    	 addVisitToTable( v.elementAt(i) );
	     }
	}
	
	private void addVisitToTable( MedicalVisit m ) {
		Object[] rowData = { m.getDate(), m.getDoctor() };
		tableModel(historyTable).addRow( rowData );
	}
	
	public MedicalVisit getMedicalVisitFromTable( int row ) {
		Vector<MedicalVisit> v = patient.getMedicalHistory();
		Date id = (Date)tableModel(historyTable).getValueAt(row, 0);
		for ( int i = 0; i < v.size(); i++ ) {
			if( v.elementAt(i).getDate().equals(id) ) {
				return v.elementAt(i);
			}
		}
		
		return null;
	}

	
	private void fillTableWithAllImages() {
		Vector<MedicalImage> v = patient.getMedicalImages();
		imagingTable.setModel( new DefaultTableModel(columnNames2, 0) );
		for( int i = 0; i < v.size(); i++ ) {
	    	 addImageToTable( v.elementAt(i) );
	     }
	}
	
	private void addImageToTable( MedicalImage m ) {
		Object[] rowData = { m.getDate(), m.getType() };
		tableModel(imagingTable).addRow( rowData );
	}
	
	public MedicalImage getMedicalImageFromTable( int row ) {
		Vector<MedicalImage> v = patient.getMedicalImages();
		Date id = (Date)tableModel(imagingTable).getValueAt(row, 0);
		for ( int i = 0; i < v.size(); i++ ) {
			if( v.elementAt(i).getDate().equals(id) ) {
				return v.elementAt(i);
			}
		}
		
		return null;
	}
	
	public DefaultTableModel tableModel(JTable t) {
		return (DefaultTableModel)(t.getModel());
	}

	public void stateChanged(ChangeEvent e) {
		
		loadMRISlide( imageChanger.getValue() );
	}
	
	private void loadMRISlide(int n) {

		File dir = new File( getMedicalImageFromTable( imagingTable.getSelectedRow() ).getPath() );
		String[] files = dir.list();
		
		try {
			if (files[n].endsWith(".png")) picLabel.setIcon( new ImageIcon( dir+ "/" + files[n] ) );
		}
		catch (Exception x) {}
	}
}
